/******************************************************
 Cours :             GTI310
 Session :           Hiver 2011
 Groupe :            01
 Projet :            TP3
 Etudiant(e)(s) :    Marceau, Francois
                     Laforest, Alexandre
 Code(s) perm. :     MARF13049006
                     SCHA20128507
                     
 Professeur :        Francois Caron
 Charge de labo.:    Jean-Francois Franche
 Nom du fichier :    ConcreteSolver.java
 Date de creation    2011-03-02
 *******************************************************
 Historique des modifications
 *******************************************************
 2011-03-02          Version initiale
 *******************************************************/

package solver;

import parser.DataInput;
import writer.DataOutput;

public class ConcreteSolver implements Solver<DataInput, DataOutput> {

	// On initialise les variables
	private int nbNodes,
	infiniteValue,
	firstSummit;

	int[][] matriceResultats; // [2] = 1: poids, 2 : parent


	public DataOutput solve(DataInput dataInput) {

		this.nbNodes = dataInput.getNbNodes();
		this.infiniteValue = dataInput.getInfiniteValue();
		this.firstSummit = dataInput.getFirstSummit();
		matriceResultats = new int[nbNodes][2];


		init(dataInput, firstSummit);


		for(int nb = 0; nb < 2; nb++){
			for(int i = 0 ; i  < nbNodes; i++){	
				for(int j = 0; j < nbNodes; j++){
					if(dataInput.getValue(i, j) != 0){
						int p =  dataInput.getValue(i, j);
						reCalculate(i,j,p);

					}

				}	
			}
		}

		for(int i = 0 ; i  < nbNodes; i++){	
			for(int j = 0; j < nbNodes; j++){		

	
				if(matriceResultats[j][0] + dataInput.getValue(i, j) < matriceResultats[j][0]){

					
					
					System.out.println("Boucle infinie detectee");
					System.exit(0);
				}
			}	
		}
		DataOutput dataOutput = new DataOutput(nbNodes, firstSummit);
		
		for(int i = 0 ; i  < nbNodes; i++){		
			dataOutput.setResults(i, 0, matriceResultats[i][0]);
			dataOutput.setResults(i, 1, matriceResultats[i][1]);
		}
		
		return dataOutput;

	}

	private void init(DataInput dataInput, int startPoint){
		for(int i = 0 ; i  < nbNodes; i++){		
			matriceResultats[i][0] = infiniteValue; // poids inf
			matriceResultats[i][1] = 0; 
		}
		matriceResultats[0][0] = 0;
		matriceResultats[0][1] = -1;

	}




	private void reCalculate(int i, int j, int p){
		/* int aa = matriceResultats[i][0] + p;
		int ab = p;
		int ac = matriceResultats[j][0]; */
		if (matriceResultats[i][0] + p < matriceResultats[j][0]){
			matriceResultats[j][0] = matriceResultats[i][0] + p;
			matriceResultats[j][1] = i+1;
		}	
	}	

}

